package cn.edu.sdjzu.xg23.kcsj01_backend.filter;

import cn.edu.sdjzu.xg23.kcsj01_backend.exception.JwtAuthenticationException;
import cn.edu.sdjzu.xg23.kcsj01_backend.utils.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        String requestURI = request.getRequestURI();
        String method = request.getMethod();
        logger.info("JWT过滤器拦截请求: {} {}", method, requestURI);

        final String authHeader = request.getHeader("Authorization");

        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            logger.info("找到Authorization头，开始处理JWT");
            String jwt = authHeader.substring(7);
            logger.info("提取的JWT令牌长度: {}", jwt.length());

            try {
                jwtUtil.validateToken(jwt); // 验证Token
                logger.info("JWT验证结果: 有效");

                String username = jwtUtil.getUsernameFromToken(jwt);
                logger.info("从JWT中解析的用户名: {}", username);

                // 解析权限
                List<String> permissions = jwtUtil.getPermissionsFromToken(jwt); // 解析权限

                // 将权限转换为Spring Security的权限对象
                Collection<GrantedAuthority> authorities = permissions.stream()
                        .map(SimpleGrantedAuthority::new)
                        .collect(Collectors.toList());

                // 打印日志（只保留权限相关信息）
                logger.info("解析的权限数量: {}", permissions.size());
                logger.info("解析的权限集合: {}", authorities);
                if (!permissions.isEmpty()) {
                    logger.debug("解析的权限明细: {}", String.join(", ", permissions));
                }

                // 设置认证对象（只包含权限）
                UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
                        username, null, authorities
                );
                auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(auth);
                logger.info("用户已认证，权限已设置，请求继续处理");

            } catch (JwtAuthenticationException e) {
                // 捕获JWT异常，记录日志并重新抛出
                logger.error("JWT验证失败: {}", e.getMessage());
                SecurityContextHolder.clearContext();
                throw e; // 直接抛出，让全局处理器处理
            } catch (Exception e) {
                logger.error("JWT处理失败: {}", e.getMessage(), e);
                SecurityContextHolder.clearContext();
            }
        } else {
            logger.info("未找到有效的Authorization头，请求继续处理");
        }

        filterChain.doFilter(request, response);
    }
}